#ifndef prs_AttrTest_H
#define prs_AttrTest_H

#include "prs_Attr.h"

namespace prs_AttrTest {
using namespace prs;
  
/*****************************************************
struct TPropString
{
TPropString() {}
//
void SetValue(const svl::TString &V) { funcSet(V);}
svl::TString GetValue() { return funcGet();}
//
void operator = (const svl::TString &V) { SetValue(V);}
void operator = (TPropString &V) { SetValue(V.GetValue());}
operator svl::TString () { return GetValue();}
//
template<class Obj,class Func>void RegisterSet(Obj obj,Func func) { funcSet.bind(obj,func);}
template<class Obj,class Func>void RegisterGet(Obj obj,Func func) { funcGet.bind(obj,func);}

private:
FastDelegate< void(svl::TString) > funcSet;
FastDelegate< svl::TString() >     funcGet;
};
****************************************************/

/*****************
struct TMouse
{
  bool                IsProcessed;
  grf::TMouse::EState State;
  grf::TShift         Shift;
  grf::TPoint         PtClient;
  TPanel             *TopComponent;
  //
  TMouse() { IsProcessed = false; TopComponent = NULL;}
****************/








///////////////////////////////////////////////////////////////////////////////

struct TValueString
{
  void SetValue(const svl::TString &V) { value = V;}
  const svl::TString &GetValue() const { return value;}

private:
  svl::TString value;
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeRoot : public TAttrNode
{
  DECLARE_ClientNode()
};

///////////////////////////////////////////////////////////////////////////////
struct TNodeTest;

struct TMessageTest : public TAttrNode
{
  DECLARE_ClientNode()
  static const char *attrName_Sender;
  static const char *attrName_OldVal;
  static const char *attrName_NewVal;
  //
  TAttrPointer<attrName_Sender,TNodeTest*> Sender;
  TAttrString<attrName_OldVal> OldVal;
  TAttrString<attrName_NewVal> NewVal;
  //
  TMessageTest() : Sender(this),OldVal(this),NewVal(this) {}
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeTest : public TAttrNode
{
  DECLARE_ClientNode()
  static const char *attrName_Receiver;
  static const char *attrName_Value;
  //
  TAttrPointerNoCopy<attrName_Receiver,IBaseReceiver*> Receiver;
  //TPropString<attrName_Value> Value;
  TAttrString<attrName_Value> Value;
  //
  TNodeTest() : Receiver(this),Value(this)
  {
    //Value.RegisterSet(this,&TNodeTest::SetValue);
    //Value.RegisterGet(&value,&TValueString::GetValue);
  }
  void operator = (TNodeTest &From) { CopyAttrFrom(&From);}

private:
  void SetValue(const svl::TString &V) {
    TMessageTest M;
      M.Sender = this;
      M.OldVal = Value;
      M.NewVal = V;
    SendMessage(M,Receiver);
    value.SetValue(M.NewVal);
  }
  TValueString value;
};

///////////////////////////////////////////////////////////////////////////////

struct TReceiver1// : public TAttrNode
 :public IReceiver<TMessageTest>
{
  //DECLARE_ClientNode()
  
  virtual void Receive(TMessageTest &Message) {
    svl::TString SOld = Message.OldVal;
    svl::TString SNew = Message.NewVal;
    TNodeTest *Sender = Message.Sender;
    Message.NewVal = "Receiver1";
  }
};

///////////////////////////////////////////////////////////////////////////////

struct TReceiver2// : public TAttrNode
 :public IReceiver<TMessageTest>
{
  //DECLARE_ClientNode()
  
  virtual void Receive(TMessageTest &Message) {
    svl::TString SOld = Message.OldVal;
    svl::TString SNew = Message.NewVal;
    TNodeTest *Sender = Message.Sender;
    Message.NewVal = "Receiver2";
  }
};

///////////////////////////////////////////////////////////////////////////////

struct TVisitorTest
 :public svl::IVisitor<TNodeRoot>
 ,public svl::IVisitor<TNodeTest>
{
  int Level;
  svl::TString SInfo;
  //
  TVisitorTest(int Level = 0) { 
    this->Level = Level;
    sOffs.FillToLen(Level*2,' ');
  }
  //
  void Visit(TNodeRoot &Node) {
    Node.AcceptChildren(*this);
  }
  //
  void Visit(TNodeTest &Node) {
    Node.AcceptChildren(*this);
  }

private:
  svl::TString sOffs;
};

///////////////////////////////////////////////////////////////////////////////
void Test();

///////////////////////////////////////////////////////////////////////////////
}

#endif

